<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Object methods</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
<link rel="start" href="index.html" title="GObject Reference Manual">
<link rel="up" href="howto-gobject.html" title="How to define and implement a new GObject">
<link rel="prev" href="howto-gobject-destruction.html" title="Object Destruction">
<link rel="next" href="howto-gobject-chainup.html" title="Chaining up">
<meta name="generator" content="GTK-Doc V1.9 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
<link rel="preface" href="pr01.html" title="Introduction">
<link rel="part" href="pt01.html" title="Part&#160;I.&#160;Concepts">
<link rel="chapter" href="chapter-intro.html" title="Background">
<link rel="chapter" href="chapter-gtype.html" title="The GLib Dynamic Type System">
<link rel="chapter" href="chapter-gobject.html" title="The GObject base class">
<link rel="chapter" href="chapter-signal.html" title="The GObject messaging system">
<link rel="reference" href="rn01.html" title="API Reference">
<link rel="reference" href="rn02.html" title="Tools Reference">
<link rel="part" href="pt02.html" title="Part&#160;IV.&#160;Tutorial">
<link rel="chapter" href="howto-gobject.html" title="How to define and implement a new GObject">
<link rel="chapter" href="howto-interface.html" title="How to define and implement interfaces">
<link rel="chapter" href="howto-signals.html" title="How to create and use signals">
<link rel="part" href="pt03.html" title="Part&#160;V.&#160;Related Tools">
<link rel="chapter" href="tools-gob.html" title="GObject builder">
<link rel="chapter" href="tools-ginspector.html" title="Graphical inspection of GObjects">
<link rel="chapter" href="tools-refdb.html" title="Debugging reference count problems">
<link rel="chapter" href="tools-gtkdoc.html" title="Writing API docs">
<link rel="index" href="ix01.html" title="Index">
<link rel="index" href="ix02.html" title="Index of deprecated symbols">
<link rel="index" href="ix03.html" title="Index of new symbols in 2.2">
<link rel="index" href="ix04.html" title="Index of new symbols in 2.4">
<link rel="index" href="ix05.html" title="Index of new symbols in 2.6">
<link rel="index" href="ix06.html" title="Index of new symbols in 2.8">
<link rel="index" href="ix07.html" title="Index of new symbols in 2.10">
<link rel="index" href="ix08.html" title="Index of new symbols in 2.12">
<link rel="index" href="ix09.html" title="Index of new symbols in 2.14">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
<td><a accesskey="p" href="howto-gobject-destruction.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="howto-gobject.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GObject Reference Manual</th>
<td><a accesskey="n" href="howto-gobject-chainup.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr></table>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="howto-gobject-methods"></a>Object methods</h2></div></div></div>
<p>
      Just as with C++, there are many different ways to define object
      methods and extend them: the following list and sections draw on C++ vocabulary.
      (Readers are expected to know basic C++ buzzwords. Those who have not had to
      write C++ code recently can refer to e.g. <a class="ulink" href="http://www.cplusplus.com/doc/tutorial/" target="_top">http://www.cplusplus.com/doc/tutorial/</a> to refresh their 
      memories.)
      </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
            non-virtual public methods,
          </p></li>
<li><p>
            virtual public methods and
          </p></li>
<li><p>
            virtual private methods
          </p></li>
</ul></div>
<p>
    </p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id3001971"></a>Non-virtual public methods</h3></div></div></div>
<p>
        These are the simplest: you want to provide a simple method which can act on your object. All you need
        to do is to provide a function prototype in the header and an implementation of that prototype
        in the source file.
</p>
<pre class="programlisting">
/* declaration in the header. */
void maman_bar_do_action (MamanBar *self, /* parameters */);
/* implementation in the source file */
void maman_bar_do_action (MamanBar *self, /* parameters */)
{
  /* do stuff here. */
}
</pre>
<p>
      </p>
<p>There is really nothing scary about this.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id3001998"></a>Virtual public methods</h3></div></div></div>
<p>
        This is the preferred way to create polymorphic GObjects. All you need to do is to
        define the common method and its class function in the public header, implement the
        common method in the source file and re-implement the class function in each object 
        which inherits from you.
</p>
<pre class="programlisting">
/* declaration in maman-bar.h. */
struct _MamanBarClass {
  GObjectClass parent;

  /* stuff */
  void (*do_action) (MamanBar *self, /* parameters */);
};
void maman_bar_do_action (MamanBar *self, /* parameters */);
/* implementation in maman-bar.c */
void maman_bar_do_action (MamanBar *self, /* parameters */)
{
  MAMAN_BAR_GET_CLASS (self)-&gt;do_action (self, /* parameters */);
}
</pre>
<p>
        The code above simply redirects the do_action call to the relevant class function. Some users,
        concerned about performance, do not provide the <code class="function">maman_bar_do_action</code>
        wrapper function and require users to dereference the class pointer themselves. This is not such
        a great idea in terms of encapsulation and makes it difficult to change the object's implementation
        afterwards, should this be needed.
      </p>
<p>
        Other users, also concerned by performance issues, declare the <code class="function">maman_bar_do_action</code>
        function inline in the header file. This, however, makes it difficult to change the
        object's implementation later (although easier than requiring users to directly dereference the class 
        function) and is often difficult to write in a portable way (the <span class="emphasis"><em>inline</em></span> keyword
        is not part of the C standard).
      </p>
<p>
        In doubt, unless a user shows you hard numbers about the performance cost of the function call,
        just <code class="function">maman_bar_do_action</code> in the source file.
      </p>
<p>
        Please, note that it is possible for you to provide a default implementation for this class method in
        the object's class_init function: initialize the klass-&gt;do_action field to a pointer to the actual
        implementation. You can also make this class method pure virtual by initializing the klass-&gt;do_action
        field to NULL:
</p>
<pre class="programlisting">
static void 
maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
{
  /* Default implementation for the virtual method. */
}

static void
maman_bar_class_init (BarClass *klass)
{
  /* pure virtual method: mandates implementation in children. */
  klass-&gt;do_action_one = NULL;
  /* merely virtual method. */
  klass-&gt;do_action_two = maman_bar_real_do_action_two;
}

void maman_bar_do_action_one (MamanBar *self, /* parameters */)
{
  MAMAN_BAR_GET_CLASS (self)-&gt;do_action_one (self, /* parameters */);
}
void maman_bar_do_action_two (MamanBar *self, /* parameters */)
{
  MAMAN_BAR_GET_CLASS (self)-&gt;do_action_two (self, /* parameters */);
}
</pre>
<p>
      </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id3002096"></a>Virtual private Methods</h3></div></div></div>
<p>
        These are very similar to Virtual Public methods. They just don't have a public function to call the
        function directly. The header file contains only a declaration of the class function:
</p>
<pre class="programlisting">
/* declaration in maman-bar.h. */
struct _MamanBarClass {
  GObjectClass parent;

  /* stuff */
  void (*helper_do_specific_action) (MamanBar *self, /* parameters */);
};
void maman_bar_do_any_action (MamanBar *self, /* parameters */);
</pre>
<p>
        These class functions are often used to delegate part of the job to child classes:
</p>
<pre class="programlisting">
/* this accessor function is static: it is not exported outside of this file. */
static void 
maman_bar_do_specific_action (MamanBar *self, /* parameters */)
{
  MAMAN_BAR_GET_CLASS (self)-&gt;do_specific_action (self, /* parameters */);
}

void maman_bar_do_any_action (MamanBar *self, /* parameters */)
{
  /* random code here */

  /* 
   * Try to execute the requested action. Maybe the requested action cannot be implemented
   * here. So, we delegate its implementation to the child class:
   */
  maman_bar_do_specific_action (self, /* parameters */);

  /* other random code here */
}
</pre>
<p>
      </p>
<p>
        Again, it is possible to provide a default implementation for this private virtual class function:
</p>
<pre class="programlisting">
static void
maman_bar_class_init (MamanBarClass *klass)
{
  /* pure virtual method: mandates implementation in children. */
  klass-&gt;do_specific_action_one = NULL;
  /* merely virtual method. */
  klass-&gt;do_specific_action_two = maman_bar_real_do_specific_action_two;
}
</pre>
<p>
      </p>
<p>
        Children can then implement the subclass with code such as:
</p>
<pre class="programlisting">
static void
maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
{
  MamanBarClass *bar_class = MAMAN_BAR_CLASS (klass);
  /* implement pure virtual class function. */
  bar_class-&gt;do_specific_action_one = maman_bar_subtype_do_specific_action_one;
}
</pre>
<p>
      </p>
</div>
</div>
</body>
</html>
